home *** CD-ROM | disk | FTP | other *** search
/ Oh!X 2000 Spring / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).7z / Oh!X 2000 Spring Special CD-ROM (Japan) (Part 2).bin / DXF / samples / multimedia / dplay / src / duel / ddutil.cpp < prev    next >
C/C++ Source or Header  |  1999-03-09  |  7KB  |  222 lines

  1. //-----------------------------------------------------------------------------
  2. // File: DDutil.cpp
  3. //
  4. // Desc: Routines for loading bitmap and palettes from resources
  5. //
  6. // Copyright (C) 1995-1999 Microsoft Corporation. All Rights Reserved.
  7. //-----------------------------------------------------------------------------
  8. #undef  WIN32_LEAN_AND_MEAN
  9. #define WIN32_LEAN_AND_MEAN
  10. #include <ddraw.h>
  11. #include "ddutil.h"
  12.  
  13.  
  14.  
  15.  
  16. //-----------------------------------------------------------------------------
  17. // Name: DDUtil_CopyBitmap()
  18. // Desc: Draw a bitmap into a DirectDrawSurface
  19. //-----------------------------------------------------------------------------
  20. HRESULT DDUtil_CopyBitmap( LPDIRECTDRAWSURFACE pdds, HBITMAP hbm, int x, int y,
  21.                            int dx, int dy )
  22. {
  23.     HDC           hdcImage;
  24.     HDC           hdc;
  25.     BITMAP        bm;
  26.     DDSURFACEDESC ddsd;
  27.     HRESULT       hr;
  28.  
  29.     if( hbm == NULL || pdds == NULL )
  30.         return E_FAIL;
  31.  
  32.     // Make sure this surface is restored.
  33.     pdds->Restore();
  34.  
  35.     // Select bitmap into a memoryDC so we can use it.
  36.     hdcImage = CreateCompatibleDC(NULL);
  37.     if( !hdcImage )
  38.     {
  39.         OutputDebugString( TEXT("CreateCompatibleDC() failed\n") );
  40.         return E_FAIL;
  41.     }
  42.     SelectObject( hdcImage, hbm );
  43.  
  44.     // Get size of the bitmap
  45.     GetObject( hbm, sizeof(bm), &bm );    // get size of bitmap
  46.     dx = dx == 0 ? bm.bmWidth  : dx;    // use the passed size, unless zero
  47.     dy = dy == 0 ? bm.bmHeight : dy;
  48.  
  49.     // Gt size of surface.
  50.     ddsd.dwSize  = sizeof(ddsd);
  51.     ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
  52.     pdds->GetSurfaceDesc(&ddsd);
  53.  
  54.     if( SUCCEEDED( hr = pdds->GetDC(&hdc) ) )
  55.     {
  56.         StretchBlt( hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage,
  57.                     x, y, dx, dy, SRCCOPY);
  58.         pdds->ReleaseDC( hdc );
  59.     }
  60.  
  61.     DeleteDC( hdcImage );
  62.  
  63.     return hr;
  64. }
  65.  
  66.  
  67.  
  68.  
  69. //-----------------------------------------------------------------------------
  70. // Name: DDUtil_LoadPalette()
  71. // Desc: Create a DirectDraw palette object from a bitmap resoure
  72. //       If the resource does not exist or NULL is passed create a
  73. //       default 332 palette.
  74. //-----------------------------------------------------------------------------
  75. LPDIRECTDRAWPALETTE DDUtil_LoadPalette( LPDIRECTDRAW pDD, TCHAR* strBitmap )
  76. {
  77.     LPDIRECTDRAWPALETTE pddPalette;
  78.     int                 i;
  79.     int                 n;
  80.     HANDLE              fh;
  81.     HRSRC               h;
  82.     LPBITMAPINFOHEADER  lpbi;
  83.     PALETTEENTRY        ape[256];
  84.     RGBQUAD*            prgb;
  85.     DWORD               dwRead;
  86.  
  87.     // Build a 332 palette as the default.
  88.     for( i=0; i<256; i++ )
  89.     {
  90.         ape[i].peRed   = (BYTE)(((i >> 5) & 0x07) * 255 / 7);
  91.         ape[i].peGreen = (BYTE)(((i >> 2) & 0x07) * 255 / 7);
  92.         ape[i].peBlue  = (BYTE)(((i >> 0) & 0x03) * 255 / 3);
  93.         ape[i].peFlags = (BYTE)0;
  94.     }
  95.  
  96.     // Gt a pointer to the bitmap resource.
  97.     if( strBitmap && ( h = FindResource( NULL, strBitmap, RT_BITMAP ) ) )
  98.     {
  99.         lpbi = (LPBITMAPINFOHEADER)LockResource( LoadResource( NULL, h ) );
  100.         if( NULL == lpbi )
  101.             OutputDebugString(TEXT("lock resource failed\n"));
  102.         prgb = (RGBQUAD*)((BYTE*)lpbi + lpbi->biSize);
  103.  
  104.         if (lpbi == NULL || lpbi->biSize < sizeof(BITMAPINFOHEADER))
  105.             n = 0;
  106.         else if (lpbi->biBitCount > 8)
  107.             n = 0;
  108.         else if (lpbi->biClrUsed == 0)
  109.             n = 1 << lpbi->biBitCount;
  110.         else
  111.             n = lpbi->biClrUsed;
  112.  
  113.         // A DIB color table has its colors stored BGR not RGB, so flip them
  114.         for(i=0; i<n; i++ )
  115.         {
  116.             ape[i].peRed   = prgb[i].rgbRed;
  117.             ape[i].peGreen = prgb[i].rgbGreen;
  118.             ape[i].peBlue  = prgb[i].rgbBlue;
  119.             ape[i].peFlags = 0;
  120.         }
  121.     }
  122.     else if( strBitmap && ( fh = CreateFile( strBitmap, GENERIC_READ,
  123.                     FILE_SHARE_READ, NULL, OPEN_EXISTING,
  124.                     FILE_ATTRIBUTE_NORMAL, NULL ) ) != INVALID_HANDLE_VALUE )
  125.     {
  126.         BITMAPFILEHEADER bf;
  127.         BITMAPINFOHEADER bi;
  128.  
  129.         ReadFile( fh, &bf, sizeof(bf), &dwRead, NULL );
  130.         ReadFile( fh, &bi, sizeof(bi), &dwRead, NULL );
  131.         ReadFile( fh, ape, sizeof(ape), &dwRead, NULL );
  132.         CloseHandle( fh );
  133.  
  134.         if( bi.biSize != sizeof(BITMAPINFOHEADER) )
  135.             n = 0;
  136.         else if( bi.biBitCount > 8 )
  137.             n = 0;
  138.         else if( bi.biClrUsed == 0 )
  139.             n = 1 << bi.biBitCount;
  140.         else
  141.             n = bi.biClrUsed;
  142.  
  143.         // A DIB color table has its colors stored BGR not RGB so flip them
  144.         for(i=0; i<n; i++ )
  145.         {
  146.             BYTE r = ape[i].peRed;
  147.             ape[i].peRed  = ape[i].peBlue;
  148.             ape[i].peBlue = r;
  149.         }
  150.     }
  151.  
  152.     pDD->CreatePalette( DDPCAPS_8BIT, ape, &pddPalette, NULL );
  153.  
  154.     return pddPalette;
  155. }
  156.  
  157.  
  158.  
  159.  
  160. //-----------------------------------------------------------------------------
  161. // Name: DDUtil_ColorMatch()
  162. // Desc: Convert a RGB color to a pysical color. We do this by leting GDI
  163. //       SetPixel() do the color matching.
  164. //-----------------------------------------------------------------------------
  165. DWORD DDUtil_ColorMatch( LPDIRECTDRAWSURFACE pdds, COLORREF rgb )
  166. {
  167.     DDSURFACEDESC ddsd;
  168.     COLORREF rgbT;
  169.     HDC      hdc;
  170.     DWORD    dw = CLR_INVALID;
  171.     HRESULT  hr;
  172.  
  173.     // Wse GDI SetPixel to color match for us
  174.     if( rgb != CLR_INVALID && SUCCEEDED( pdds->GetDC(&hdc) ) )
  175.     {
  176.         rgbT = GetPixel( hdc, 0, 0 );   // Save current pixel value
  177.         SetPixel( hdc, 0, 0, rgb );     // Set our value
  178.         pdds->ReleaseDC( hdc );
  179.     }
  180.  
  181.     // Now lock the surface so we can read back the converted color
  182.     ddsd.dwSize = sizeof(ddsd);
  183.     while( ( hr = pdds->Lock( NULL, &ddsd, 0, NULL ) ) == DDERR_WASSTILLDRAWING )
  184.     {}
  185.  
  186.     if( SUCCEEDED(hr) )
  187.     {
  188.         dw  = *(DWORD *)ddsd.lpSurface;                     // get DWORD
  189.         dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount)-1;  // mask it to bpp
  190.         pdds->Unlock(NULL);
  191.     }
  192.  
  193.     // Now put the color that was there back.
  194.     if( rgb != CLR_INVALID && SUCCEEDED( pdds->GetDC(&hdc) ) )
  195.     {
  196.         SetPixel( hdc, 0, 0, rgbT );
  197.         pdds->ReleaseDC( hdc );
  198.     }
  199.  
  200.     return dw;
  201. }
  202.  
  203.  
  204.  
  205.  
  206. //-----------------------------------------------------------------------------
  207. // Name: DDUtil_SetColorKey()
  208. // Desc: Set a color key for a surface, given a RGB. If you pass CLR_INVALID as
  209. //       the color key, the pixel in the upper-left corner will be used.
  210. //-----------------------------------------------------------------------------
  211. HRESULT DDUtil_SetColorKey( LPDIRECTDRAWSURFACE pdds, COLORREF rgb )
  212. {
  213.     DDCOLORKEY ddck;
  214.     ddck.dwColorSpaceLowValue  = DDUtil_ColorMatch( pdds, rgb );
  215.     ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
  216.  
  217.     return pdds->SetColorKey( DDCKEY_SRCBLT, &ddck );
  218. }
  219.  
  220.  
  221.  
  222.